package czk.concrent.stampLock.stampLockPractice;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.StampedLock;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/6/2 14:24
 */
public class StampedLockDemo4 {
    public static void main(String[] args) {
        // 先获取乐观读锁
        StampedLock stampedLock = new StampedLock();
        new Thread(() -> {
            long l = 0L;
            try {
                l = stampedLock.tryOptimisticRead();
                System.out.println("获取乐观读锁了");
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                // 释放锁
                // 如果此时发送异常，说明乐观锁期间有写锁进入
                if (stampedLock.validate(l)) {
                    stampedLock.unlock(l);
                } else {
                    System.out.println("乐观锁期间有写锁进入");
                    // 此时做自己的业务处理，从新读或者其他补偿措施
                }

            }
        }).start();
        // 再获取写锁
        new Thread(() -> {
            long writeLock = 0L;
            try {
                // 此时应该不会阻塞
                writeLock = stampedLock.writeLock();
                System.out.println("获取写锁了");
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 释放锁，此时
                stampedLock.unlock(writeLock);
            }
        }).start();
    }
}
